Fix show_registers() on x86/64. Get rid of
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Fri, 3 Feb 2006 19:30:54 +0000 (20:30 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Fri, 3 Feb 2006 19:30:54 +0000 (20:30 +0100)
GUEST_CONTEXT() macro and the eflags==0 hack to detect
an HVM-guest stack frame. Various cleanups and fixes.

Signed-off-by: Keir Fraser <keir@xensource.com>
xen/arch/x86/boot/x86_64.S
xen/arch/x86/domain.c
xen/arch/x86/hvm/svm/x86_32/exits.S
xen/arch/x86/hvm/vmx/x86_32/exits.S
xen/arch/x86/traps.c
xen/arch/x86/x86_32/traps.c
xen/arch/x86/x86_64/entry.S
xen/arch/x86/x86_64/traps.c
xen/include/asm-x86/regs.h

index 3ab012aad84b3328021e04358763b22b42c8db76..ffcd144811f817f78173076a7c0da8ef2089bdf7 100644 (file)
@@ -185,6 +185,7 @@ int_msg:
 ignore_int:
         cld
         leaq    int_msg(%rip),%rdi
+        xorl    %eax,%eax
         call    printf
 1:      jmp     1b
 
index ce4a321e6febc0c6b5ef843c9cf32e5e1d684b26..f70d5ea3291b13d7015171281f859e738b1827ff 100644 (file)
@@ -384,7 +384,7 @@ int arch_set_info_guest(
     }
     else if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
     {
-       hvm_modify_guest_state(v);
+        hvm_modify_guest_state(v);
     }
 
     if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
@@ -433,10 +433,10 @@ int arch_set_info_guest(
             d->arch.phys_table = v->arch.guest_table;
         v->arch.guest_table = mk_pagetable(0);
 
-       if (!hvm_initialize_guest_resources(v))
+        if ( !hvm_initialize_guest_resources(v) )
             return -EINVAL;
-          
-       hvm_switch_on = 1;
+
+        hvm_switch_on = 1;
     }
 
     update_pagetables(v);
@@ -613,7 +613,7 @@ static void save_segments(struct vcpu *v)
     unsigned int dirty_segment_mask = 0;
 
     if ( HVM_DOMAIN(v) )
-       hvm_save_segments(v);
+        hvm_save_segments(v);
 
     __asm__ __volatile__ ( "mov %%ds,%0" : "=m" (regs->ds) );
     __asm__ __volatile__ ( "mov %%es,%0" : "=m" (regs->es) );
@@ -773,7 +773,7 @@ void context_switch(struct vcpu *prev, struct vcpu *next)
         {
             load_LDT(next);
             load_segments(next);
-           if ( HVM_DOMAIN(next) )
+            if ( HVM_DOMAIN(next) )
                 hvm_load_msrs(next);
         }
     }
@@ -964,7 +964,7 @@ void domain_relinquish_resources(struct domain *d)
             v->arch.guest_table_user = mk_pagetable(0);
         }
 
-       if ( HVM_DOMAIN(v) )
+        if ( HVM_DOMAIN(v) )
             hvm_relinquish_guest_resources(v);
     }
 
index c5d3e7d8f90004b6d77bb46707fec19129e50a30..9528f16a1e46be9cfb7f207af61f0582514b83c1 100644 (file)
@@ -62,7 +62,6 @@
         pushl $HVM_MONITOR_EFLAGS; \
         popf; \
         subl $(NR_SKIPPED_REGS*4), %esp; \
-        movl $0, 0xc(%esp); /* eflags==0 identifies cpu_user_regs as HVM guest */ \
         pushl %eax; \
         pushl %ebp; \
         pushl %edi; \
index abf212617bd4632d95b0fee3f9864d4cc26216d8..5650683a0616bd6090c255fbfdfcd14a4eea9b77 100644 (file)
@@ -61,7 +61,6 @@
         pushl $HVM_MONITOR_EFLAGS; \
         popf; \
         subl $(NR_SKIPPED_REGS*4), %esp; \
-        movl $0, 0xc(%esp); /* eflags==0 identifies cpu_user_regs as HVM guest */ \
         pushl %eax; \
         pushl %ebp; \
         pushl %edi; \
index b902f3d495ba13777a92e7a8e98ae75ca2b470b7..4ef114eb0b3514058432dae47f29c408adcd7ead 100644 (file)
@@ -132,6 +132,9 @@ static void show_guest_stack(struct cpu_user_regs *regs)
     int i;
     unsigned long *stack, addr;
 
+    if ( HVM_DOMAIN(current) )
+        return;
+
     if ( VM86_MODE(regs) )
     {
         stack = (unsigned long *)((regs->ss << 4) + (regs->esp & 0xffff));
@@ -251,7 +254,7 @@ void show_stack(struct cpu_user_regs *regs)
     unsigned long *stack = ESP_BEFORE_EXCEPTION(regs), addr;
     int i;
 
-    if ( GUEST_CONTEXT(current, regs) )
+    if ( GUEST_MODE(regs) )
         return show_guest_stack(regs);
 
     printk("Xen stack trace from "__OP"sp=%p:\n   ", stack);
@@ -498,7 +501,7 @@ static int fixup_page_fault(unsigned long addr, struct cpu_user_regs *regs)
 
     if ( unlikely(IN_HYPERVISOR_RANGE(addr)) )
     {
-        if ( shadow_mode_external(d) && GUEST_CONTEXT(v, regs) )
+        if ( shadow_mode_external(d) && GUEST_MODE(regs) )
             return shadow_fault(addr, regs);
         if ( (addr >= GDT_LDT_VIRT_START) && (addr < GDT_LDT_VIRT_END) )
             return handle_gdt_ldt_mapping_fault(
index 4422ca2530f44d12aaeeddc33aa2b987d7536298..16829ed49913f475e915d48f3defba288bb00d5e 100644 (file)
@@ -18,57 +18,51 @@ idt_entry_t *idt_tables[NR_CPUS] = { 0 };
 
 void show_registers(struct cpu_user_regs *regs)
 {
-    struct cpu_user_regs faultregs;
-    unsigned long faultcrs[8];
+    struct cpu_user_regs fault_regs = *regs;
+    unsigned long fault_crs[8];
     const char *context;
 
-    if ( HVM_DOMAIN(current) && regs->eflags == 0 )
+    if ( HVM_DOMAIN(current) && GUEST_MODE(regs) )
     {
-       context = "hvm";
-       hvm_load_cpu_guest_regs(current, &faultregs);
-       hvm_store_cpu_guest_ctrl_regs(current, faultcrs);
+        context = "hvm";
+        hvm_store_cpu_guest_regs(current, &fault_regs);
+        hvm_store_cpu_guest_ctrl_regs(current, fault_crs);
     }
     else
     {
-       faultregs = *regs;
-        if ( GUEST_MODE(regs) )
+        context = GUEST_MODE(regs) ? "guest" : "hypervisor";
+
+        if ( !GUEST_MODE(regs) )
         {
-            context = "guest";
-            faultregs.ss &= 0xFFFF;
-            faultregs.ds &= 0xFFFF;
-            faultregs.es &= 0xFFFF;
-            faultregs.cs &= 0xFFFF;
-       }
-       else 
-       {
-            context = "hypervisor";
-            faultregs.esp = (unsigned long)&regs->esp;
-            faultregs.ss = __HYPERVISOR_DS;
-            faultregs.ds = __HYPERVISOR_DS;
-            faultregs.es = __HYPERVISOR_DS;
-            faultregs.cs = __HYPERVISOR_CS;
-       }
-        __asm__ ("movw %%fs,%0 ; movw %%gs,%1"
-                : "=r" (faultregs.fs), "=r" (faultregs.gs) );
-
-       faultcrs[0] = read_cr0();
-       faultcrs[3] = read_cr3();
+            fault_regs.esp = (unsigned long)&regs->esp;
+            fault_regs.ss = __HYPERVISOR_DS;
+            fault_regs.ds = __HYPERVISOR_DS;
+            fault_regs.es = __HYPERVISOR_DS;
+            fault_regs.cs = __HYPERVISOR_CS;
+        }
+
+        __asm__ (
+            "movw %%fs,%0 ; movw %%gs,%1"
+            : "=r" (fault_regs.fs), "=r" (fault_regs.gs) );
+        
+        fault_crs[0] = read_cr0();
+        fault_crs[3] = read_cr3();
     }
 
     printk("CPU:    %d\nEIP:    %04x:[<%08x>]",
-           smp_processor_id(), faultregs.cs, faultregs.eip);
-    if ( !HVM_DOMAIN(current) && !GUEST_MODE(regs) )
-        print_symbol(" %s", faultregs.eip);
-    printk("\nEFLAGS: %08x   CONTEXT: %s\n", faultregs.eflags, context);
+           smp_processor_id(), fault_regs.cs, fault_regs.eip);
+    if ( !GUEST_MODE(regs) )
+        print_symbol(" %s", fault_regs.eip);
+    printk("\nEFLAGS: %08x   CONTEXT: %s\n", fault_regs.eflags, context);
     printk("eax: %08x   ebx: %08x   ecx: %08x   edx: %08x\n",
-           regs->eax, regs->ebx, regs->ecx, regs->edx);
+           fault_regs.eax, fault_regs.ebx, fault_regs.ecx, fault_regs.edx);
     printk("esi: %08x   edi: %08x   ebp: %08x   esp: %08x\n",
-           regs->esi, regs->edi, regs->ebp, faultregs.esp);
-    printk("cr0: %08lx   cr3: %08lx\n", faultcrs[0], faultcrs[3]);
+           fault_regs.esi, fault_regs.edi, fault_regs.ebp, fault_regs.esp);
+    printk("cr0: %08lx   cr3: %08lx\n", fault_crs[0], fault_crs[3]);
     printk("ds: %04x   es: %04x   fs: %04x   gs: %04x   "
            "ss: %04x   cs: %04x\n",
-           faultregs.ds, faultregs.es, faultregs.fs,
-          faultregs.gs, faultregs.ss, faultregs.cs);
+           fault_regs.ds, fault_regs.es, fault_regs.fs,
+           fault_regs.gs, fault_regs.ss, fault_regs.cs);
 
     show_stack(regs);
 }
index e878fe4b6a931e1933e3785a83ca7c8434c16ac9..6e40b30c7f1be1961fb95cfa8e8a0d77330d69df 100644 (file)
@@ -311,8 +311,15 @@ domain_crash_synchronous_string:
         .asciz "domain_crash_sync called from entry.S\n"
 
 domain_crash_synchronous:
-        leaq domain_crash_synchronous_string(%rip),%rdi
-        call printf
+        # Get out of the guest-save area of the stack.
+        GET_GUEST_REGS(%rax)
+        movq  %rax,%rsp
+        # create_bounce_frame() temporarily clobbers CS.RPL. Fix up.
+        orb   $3,UREGS_cs(%rsp)
+        # printk(domain_crash_synchronous_string)
+        leaq  domain_crash_synchronous_string(%rip),%rdi
+        xorl  %eax,%eax
+        call  printf
         jmp  __domain_crash_synchronous
 
         ALIGN
@@ -468,6 +475,18 @@ ENTRY(double_fault)
 ENTRY(nmi)
         pushq $0
         SAVE_ALL
+        testb $3,UREGS_cs(%rsp)
+        jz    nmi_in_hypervisor_mode
+        /* Interrupted guest context. Copy the context to stack bottom. */
+        GET_GUEST_REGS(%rbx)
+        addq  $UREGS_kernel_sizeof,%rbx
+        movl  $UREGS_kernel_sizeof/8,%ecx
+1:      popq  %rax
+        subq  $8,%rbx
+        movq  %rax,(%rbx)
+        loop  1b
+        movq  %rbx,%rsp
+nmi_in_hypervisor_mode:
         movq  %rsp,%rdi
         call  do_nmi
         jmp   ret_from_intr
index 297cba2242d9a744aec7e0f7bd92aadbf5d51930..8f66023b75c485c66a5d1dd5a74057566057b194 100644 (file)
 
 void show_registers(struct cpu_user_regs *regs)
 {
-    struct cpu_user_regs faultregs;
-    unsigned long faultcrs[8];
+    struct cpu_user_regs fault_regs = *regs;
+    unsigned long fault_crs[8];
     const char *context;
 
-    if ( HVM_DOMAIN(current) && regs->eflags == 0 )
+    if ( HVM_DOMAIN(current) && GUEST_MODE(regs) )
     {
-       context = "hvm";
-       hvm_load_cpu_guest_regs(current, &faultregs);
-       hvm_store_cpu_guest_ctrl_regs(current, faultcrs);
+        context = "hvm";
+        hvm_store_cpu_guest_regs(current, &fault_regs);
+        hvm_store_cpu_guest_ctrl_regs(current, fault_crs);
     }
     else
     {
-       faultregs = *regs;
-
-        if ( GUEST_MODE(regs) )
-        {
-            context = "guest";
-       }
-       else 
-       {
-            context = "hypervisor";
-            faultregs.esp = (unsigned long)&regs->esp;
-       }
-
-       faultcrs[0] = read_cr0();
-       faultcrs[3] = read_cr3();
+        context = GUEST_MODE(regs) ? "guest" : "hypervisor";
+        fault_crs[0] = read_cr0();
+        fault_crs[3] = read_cr3();
     }
 
     printk("CPU:    %d\nRIP:    %04x:[<%016lx>]",
-           smp_processor_id(), faultregs.cs, faultregs.rip);
-    if ( !HVM_DOMAIN(current) && !GUEST_MODE(regs) )
-        print_symbol(" %s", faultregs.rip);
-
-    printk("\nRFLAGS: %016lx   CONTEXT: %s\n", faultregs.rflags, context);
+           smp_processor_id(), fault_regs.cs, fault_regs.rip);
+    if ( !GUEST_MODE(regs) )
+        print_symbol(" %s", fault_regs.rip);
+    printk("\nRFLAGS: %016lx   CONTEXT: %s\n", fault_regs.rflags, context);
     printk("rax: %016lx   rbx: %016lx   rcx: %016lx\n",
-           regs->rax, regs->rbx, regs->rcx);
+           fault_regs.rax, fault_regs.rbx, fault_regs.rcx);
     printk("rdx: %016lx   rsi: %016lx   rdi: %016lx\n",
-           regs->rdx, regs->rsi, regs->rdi);
+           fault_regs.rdx, fault_regs.rsi, fault_regs.rdi);
     printk("rbp: %016lx   rsp: %016lx   r8:  %016lx\n",
-           regs->rbp, faultregs.rsp, regs->r8);
+           fault_regs.rbp, fault_regs.rsp, fault_regs.r8);
     printk("r9:  %016lx   r10: %016lx   r11: %016lx\n",
-           regs->r9,  regs->r10, regs->r11);
+           fault_regs.r9,  fault_regs.r10, fault_regs.r11);
     printk("r12: %016lx   r13: %016lx   r14: %016lx\n",
-           regs->r12, regs->r13, regs->r14);
+           fault_regs.r12, fault_regs.r13, fault_regs.r14);
     printk("r15: %016lx   cr0: %016lx   cr3: %016lx\n",
-           regs->r15, faultcrs[0], faultcrs[3]);
+           fault_regs.r15, fault_crs[0], fault_crs[3]);
 
     show_stack(regs);
 }
index dfa0868e448f4805a028a68224db8a7a22fbc190..8c88d5394b47195ecf7cdcefb5015cae8dffc31d 100644 (file)
@@ -31,8 +31,17 @@ enum EFLAGS {
     EF_ID   = 0x00200000,   /* id */
 };
 
-#define GUEST_MODE(_r) (likely(VM86_MODE(_r) || !RING_0(_r)))
-
-#define GUEST_CONTEXT(_ed, _r) ((HVM_DOMAIN(_ed) && ((_r)->eflags == 0)) || GUEST_MODE(_r))
+#define GUEST_MODE(r)                                                         \
+({                                                                            \
+    unsigned long diff = (char *)guest_cpu_user_regs() - (char *)(r);         \
+    /* Frame pointer must point into current CPU stack. */                    \
+    ASSERT(diff < STACK_SIZE);                                                \
+    /* If a guest frame, it must not be a ring 0 frame (unless HVM guest). */ \
+    ASSERT((diff != 0) || VM86_MODE(r) || !RING_0(r) || HVM_DOMAIN(current)); \
+    /* If not a guest frame, it must be a ring 0 frame. */                    \
+    ASSERT((diff == 0) || (!VM86_MODE(r) && RING_0(r)));                      \
+    /* Return TRUE if it's a guest frame. */                                  \
+    (diff == 0);                                                              \
+})
 
 #endif /* __X86_REGS_H__ */